#TODO: Make a base class that extends the couchdb.schema.Document and stores the database connection with the document

import couchdb.schema

class Document(couchdb.schema.Document):
    
    def load(cls, db, id):
        """Load a specific document from the given database.
        
        :param db: the `Database` object to retrieve the document from
        :param id: the document ID
        :return: the `Document` instance, or `None` if no document with the
                 given ID was found
        """
        o = couchdb.schema.Document.load(cls, db, id)
        if o is not None:
            o._db = db
        return o
    load = classmethod(load)
    
    def store(self,db=None):
        if db is None:
            db = self._db
        return couchdb.schema.Document.store(self,db)

    def query(cls, db, map_fun, reduce_fun, language='javascript',
              eager=False, **options):
        """Execute a CouchDB temporary view and map the result values back to
        objects of this schema.
        
        Note that by default, any properties of the document that are not
        included in the values of the view will be treated as if they were
        missing from the document. If you'd rather want to load the full
        document for every row, set the `eager` option to `True`, but note that
        this will initiate a new HTTP request for every document, unless the
        `include_docs` option is explitly specified.
        """
        def _wrapper(row):
            if eager:
                if row.doc is not None:
                    row.doc._db = db
                    return row.doc
                return cls.load(db, row.id)
            data = row.value
            data['_id'] = row.id
            o = cls.wrap(data)
            o._db = db
            return o
        return db.query(map_fun, reduce_fun=reduce_fun, language=language,
                        wrapper=_wrapper, **options)
    query = classmethod(query)